package com.simple.orm.agreement.process.impl;

import com.simple.orm.agreement.annotation.AgreementProcess;
import com.simple.orm.agreement.process.WriteProcess;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class AutoWriteProcess {

    public static <T> byte[] writeTo(T t, WriteProcess.DescribeEvent describeEvent) throws IOException {
        Class<T> aClass = (Class<T>) t.getClass();
        AgreementProcess agreementProcess = aClass.getDeclaredAnnotation(AgreementProcess.class);
        Class<? extends WriteProcess> writeProcess = DefaultWriteProcess.class;
        if (agreementProcess != null) writeProcess = agreementProcess.writeProcess();
        WriteProcess instance = instance(writeProcess);
        instance.setDescribeEvent(describeEvent);
        return instance.writeTo(t);
    }

    /**
     * 实例化对象
     *
     * @param tClass 被实例化的对象的类对象
     * @return 实例化的对象
     */
    protected static <T> T instance(Class<T> tClass) {
        Constructor<T>[] constructors = (Constructor<T>[]) tClass.getDeclaredConstructors();
        for (Constructor<T> constructor : constructors) {
            if (constructor.getParameterCount() > 0) continue;
            boolean accessible = constructor.isAccessible();
            try {
                return constructor.newInstance();
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            } finally {
                constructor.setAccessible(accessible);
            }
        }
        throw new IllegalArgumentException("找不到无参构造方法，无法实例化目标");
    }
}
